﻿using HighPerformanceLog.V0;
using System;
using System.Collections;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace HighPerformanceLog.V1
{
    /// <summary>
    /// 日志对象，包括主要日志属性。
    /// </summary>
    public class HWLog
    {
        /// <summary>
        /// 日志产生的时间，即 var log = new Log() 的时间，也可以初始化后对 log.Time 进行修改。。
        /// </summary>
        public DateTime Time { get; set; } = DateTime.Now;

        /// <summary>
        /// 日志的严重程度。
        /// </summary>
        public LogSeverity Severity { get; set; } = 0;

        /// <summary>
        /// 日志的类型，默认值未指定。
        /// </summary>
        public LogCategory Category { get; set; } = LogCategory.None;

        /// <summary>
        /// 代码所在文件的全路径，如 QTrans.SQLHelper.GetData，默认值为""。
        /// </summary>
        public string Method { get; set; } = "";

        /// <summary>
        /// 代码所在的文件行，如 QTrans.cs@447
        /// </summary>
        public string Position { get; set; } = "";


        /// <summary>
        /// 日志消息的内容。
        /// </summary>
        public string Content { get; set; } = "";


        public HWLog() { } 


        /// <summary>
        /// 格式为 2022/06/15 10:09:46 2 Hao.Utils.HWLog::Log@114 -> hello2
        /// </summary>
        /// <returns></returns>
        public override string ToString()
        {
            var content = Content.Replace("\t", "\\t").Replace("\n", "\\n").Replace("\r", "\\r");  
            return $"{DateTime.Now:yyyy/MM/dd HH:mm:ss.fff}\t{Severity}\t{Category}\t{Method}\t{Position}\t{content}";
        }


        public static List<HWLog> GenerateRandomLogs(int count = 1000)
        {
            var logs = new List<HWLog>();
            Random rand = new Random();
            LogSeverity[] severities = new LogSeverity[6] { LogSeverity.FATAL, LogSeverity.ERROR, LogSeverity.WARNING, LogSeverity.INFO, LogSeverity.DEBUG, LogSeverity.NONE };
            for (int i = 0; i < count; i++)
            {
                logs.Add(new HWLog()
                {
                    Severity = severities[rand.Next(severities.Length)],
                    Category = LogCategory.Login_10100,
                    Content = "hello" + i
                }) ;
            }
            return logs;
        }

        public static List<HWLog> LoadLogs(string path)
        {
            var logs = new List<HWLog>();

            if (File.Exists(path))
            {
                foreach (string line in File.ReadLines(path))
                {
                    HWLog log = HWLog.Parse(line);
                    if(log != null) 
                        logs.Add(log);
                }
            }

            return logs;
        }

        public static HWLog Parse(string line)
        {
            HWLog log = new HWLog();

            try
            {
                var ss = line.Split('\t');
                log.Time = DateTime.Parse(ss[0]);
                log.Severity = (LogSeverity)Enum.Parse(typeof(LogSeverity), ss[1]);
                log.Category = (LogCategory)Enum.Parse(typeof(LogCategory), ss[2]);
                log.Method = ss[3];
                log.Position = ss[4];
                log.Content = ss[5]; 
            }
            catch
            {
                log = null;
            }


            return log;
        }

        public void AttachStackFramInfo()
        {
            var st = Functions.GetStackFrame(2);
            if (st != null)
            {
                Method = st.GetMethod().DeclaringType.FullName + "." + st.GetMethod().Name;
                Position = st.GetFileName() + "@" + st.GetFileLineNumber();
            }
        }
    }
}
